package com.ruiya.staging.goods.dataio.service;

import com.ruiya.staging.goods.data.grpc.*;
import com.ruiya.staging.goods.data.grpc.DataIOServiceGrpc.DataIOServiceImplBase;
import com.ruiya.staging.goods.dataio.dao.GoodsInfoDao;
import com.ruiya.staging.goods.dataio.model.GoodsInfoDO;
import com.ruiya.staging.goods.dataio.util.DataIORpcStatus;
import com.ruiya.staging.goods.dataio.util.GrpcResponseUtils;
import com.ruiya.staging.goods.dataio.mapper.MapperDO;
import io.grpc.stub.StreamObserver;
import org.apache.commons.lang3.tuple.Pair;
import net.devh.boot.grpc.server.service.GrpcService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.text.MessageFormat;

@GrpcService
public class GoodsInfoService extends DataIOServiceImplBase {
    private static final Logger _log = LoggerFactory.getLogger(GoodsInfoDao.class);

    @Autowired
    private GoodsInfoDao goodsInfoDao;

    @Override
    public void echo(EchoRequest request, StreamObserver<EchoResponse> responseObserver) {
        String tid = "";
        try {
            tid = request.getUri().getTid();
            EchoResponse response = EchoResponse.newBuilder()
                    .setStatus(DataIORpcStatus.ok())
                    .setName(request.getName())
                    .build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
        } catch (Exception ex) {
            _log.error(MessageFormat.format("echo, tid={0}", tid), ex);
            GrpcResponseUtils.doEchoError(responseObserver, RpcStatus.Codes.Exception_VALUE, ex.getMessage());
        }
    }

    @Override
    public void createGoodsInfo(CreateGoodsInfoRequest request, StreamObserver<CreateGoodsInfoResponse> responseObserver) {
        String tid = "";
        try {
            tid = request.getUri().getTid();
            String sharding = request.getUri().getSharding();
            GoodsInfo goodsInfo = request.getGoodsInfo();

            Pair<Boolean, String> result = goodsInfoDao.createGoodsInfo(sharding, MapperDO.mapToGoodsInfoDO(goodsInfo));
            if (!result.getKey()) {
                GrpcResponseUtils.doCreateGoodsInfoError(responseObserver, RpcStatus.Codes.DBFail_VALUE, "insert error");
                return;
            }

            CreateGoodsInfoResponse response = CreateGoodsInfoResponse.newBuilder()
                    .setStatus(DataIORpcStatus.ok())
                    .setGoodsId(request.getGoodsInfo().getGoodsId())
                    .build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
        } catch (Exception ex) {
            _log.error(MessageFormat.format("createGoodsInfo, tid={0}", tid), ex);
            GrpcResponseUtils.doCreateGoodsInfoError(responseObserver, RpcStatus.Codes.Exception_VALUE, ex.getMessage());
        }


    }

    @Override
    public void getGoodsInfo(GetGoodsInfoRequest request, StreamObserver<GetGoodsInfoResponse> responseObserver) {
        String tid = "";
        try {
            String sharding = request.getUri().getSharding();
            String goodsId = request.getGoodsId();

            GoodsInfoDO goodsInfoDTO = goodsInfoDao.getGoodsInfo(sharding, goodsId);

            GetGoodsInfoResponse response = GetGoodsInfoResponse.newBuilder()
                    .setStatus(DataIORpcStatus.ok())
                    .setGoodsInfo(MapperDO.mapFromGoodsInfoDTO(goodsInfoDTO))
                    .build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
        } catch (Exception ex) {
            _log.error(MessageFormat.format("getGoodsInfo, tid={0}", tid), ex);
            GrpcResponseUtils.doGetGoodsInfoResponseError(responseObserver, RpcStatus.Codes.Exception_VALUE, ex.getMessage());
        }
    }

    @Override
    public void locateGoodsId(LocateGoodsIdRequest request, StreamObserver<LocateGoodsIdResponse> responseObserver) {
        try {
            String goodsNo = request.getGoodsNo();

            String goodsId = goodsInfoDao.locateGoodsId(goodsNo);

            LocateGoodsIdResponse response = LocateGoodsIdResponse.newBuilder()
                    .setStatus(RpcStatus.newBuilder().setCode(0).setMemo("ok").build())
                    .setGoodsId(goodsId)
                    .build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
        } catch (Exception ex){
            _log.error("locateGoodsId", ex);
            GrpcResponseUtils.doLocateGoodsIdError(responseObserver, RpcStatus.Codes.Exception_VALUE, ex.getMessage());
        }
    }
}
